package com.zhht.checkcop.util;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * 
 * <p>Title:SHA1 </p>
 * <p>Description:使用SHA1加密 </p>
 * @author PanBaihui
 * @date 2017年8月16日 下午2:03:29
 */
public class SHA1 {
	
	private static String[] HexCode = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};
	
	private static String appKey = "1234567894521E34SDF994ASDES3";
	
	/**
	 * 
	 * @Title: isTrueSign 
	 * @Description: TODO(验证APP签名正确性) 
	 * @param entity
	 * @param sign 不签名字段
	 * @return boolean    返回类型 
	 * @throws
	 * 注意使用该方法的entity不能有除属性外其他的get方法否则签名验证失败
	 */
	public static <T> boolean isTrueSign(T entity,String sign) {
		try {
			String appSign = EntityFieldUtil.getFieldValue(entity, sign).toString();
			String serverSign = buildRequestMysign(EntityFieldUtil.getEntityFieldMap(entity,sign));
			return appSign.equals(serverSign);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}
	
    /**
     * 生成签名结果
     * @param sPara 要签名的数组
     * @return 签名结果字符串
     */
	public static String buildRequestMysign(Map<String, Object> sPara) {
    	String prestr = createLinkString(sPara); //把数组所有元素，按照“参数=参数值”的模式用“&”字符拼接成字符串
        return signature(prestr,appKey);
    }
	
    /** 
     * 把数组所有元素排序，并按照“参数=参数值”的模式用“&”字符拼接成字符串
     * @param params 需要排序并参与字符拼接的参数组
     * @return 拼接后字符串
     */
    public static String createLinkString(Map<String, Object> params) {

        List<String> keys = new ArrayList<String>(params.keySet());
        Collections.sort(keys);

        String prestr = "";

        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            String value = params.get(key).toString();

            if (i == keys.size() - 1) {//拼接时，不包括最后一个&字符
                prestr = prestr + key + "=" + value;
            } else {
                prestr = prestr + key + "=" + value + "&";
            }
        }

        return prestr;
    }
    
    /**
     * 根据参数和key签名
     * @param inStr
     * @param key
     * @return
     */
	public static String signature(String inStr,String key) {
		MessageDigest md = null;
		String outStr = null;
		try {
			inStr = MD5.signature(inStr + key);
			md = MessageDigest.getInstance("SHA-1");
			byte[] digest = md.digest(inStr.getBytes());
			//outStr = bytetoString(digest);
			outStr = byteArrayToHexString(digest);
		} catch (NoSuchAlgorithmException nsae) {
			nsae.printStackTrace();
		}
		return outStr;
	}
	
	/**
	 * 将byte[]组转成string
	 * @param digest
	 * @return
	 */
	public static String bytetoString(byte[] digest) {
		String str = "";
		String tempStr = "";

		for (int i = 1; i < digest.length; i++) {
			tempStr = (Integer.toHexString(digest[i] & 0xff));
			if (tempStr.length() == 1) {
				str = str + "0" + tempStr;
			} else {
				str = str + tempStr;
			}
		}
		return str.toLowerCase();
	}
	
	public static String byteArrayToHexString(byte[] b) {
        String result = "";
        for (int i = 0; i < b.length; i++) {
            result = result + byteToHexString(b[i]);
        }
        return result;
    }
	
	public static String byteToHexString(byte b) {
        int n = b;
        if (n < 0) {
            n = 256 + n;
        }
        int d1 = n / 16;
        int d2 = n % 16;
        return HexCode[d1] + HexCode[d2];
    }
	
	 /**
	 * 构造签名源数据
	 * @param map,linkedHashMap
	 * @return
	 * @throws Exception
	 */
	public static String buildEncryptString(Map map) 
		throws Exception{
		String sign_src = "";
		Iterator iter = map.entrySet().iterator();
		while (iter.hasNext()) {
			Map.Entry entry = (Map.Entry) iter.next();
			Object value = entry.getValue();
			if(value == null) continue;
			sign_src += entry.getValue();
		}
		return sign_src;
	}
}
